use std::future::Future;
use actix::prelude::*;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use criterion::async_executor::AsyncExecutor;

// 定义一个Actor
struct Counter;

// 为Counter实现Actor trait
impl Actor for Counter {
    type Context = Context<Self>;
}

// 定义消息类型
struct Increment;

// 为消息实现Message trait
impl Message for Increment {
    type Result = ();
}

// 实现消息处理器
impl Handler<Increment> for Counter {
    type Result = ();

    fn handle(&mut self, _msg: Increment, _ctx: &mut Context<Self>) {
        // 消息处理逻辑，这里只是简单地计数
    }
}

struct Rt(SystemRunner);

impl AsyncExecutor for Rt {
    fn block_on<T>(&self, future: impl Future<Output=T>) -> T {
        self.0.block_on(future)
    }
}

impl AsyncExecutor for &Rt {
    fn block_on<T>(&self, future: impl Future<Output=T>) -> T {
        (*self).0.block_on(future)
    }
}

fn bench_simple(c: &mut Criterion) {
    let mut group = c.benchmark_group("My Group");

    // Now we can perform benchmarks with this group
    group.bench_function("Bench 1", |b| b.iter(|| 1 ));
    group.bench_function("Bench 2", |b| b.iter(|| 2 ));

    group.finish();
}

// 基准测试函数
fn throughput(c: &mut Criterion) {
    let mut group = c.benchmark_group("send_zst");
    for num_messages in [1, 10, 100, 1000,10000,100000] {
        group.bench_with_input(
            BenchmarkId::from_parameter(num_messages),
            &num_messages,
            |b, &num_messages| {
                // 在基准测试的闭包中创建本地任务集合
                let local = tokio::task::LocalSet::new();
                let sys = System::new();

                b.to_async(&Rt(sys)).iter(|| {
                    local.run_until(async {
                        // 启动actor
                        let addr = Counter.start();

                        for _ in 0..num_messages {
                            addr.do_send(Increment);
                        }
                    })
                });
            },
        );
    }
}

criterion_group!(benches, throughput, bench_simple);
criterion_main!(benches);
